跳到主要内容

SpringSecurity OAuth GitHub 登陆案例

参考资料 What is OAuth really all about - OAuth tutorial - Java Brains 参考资料 官方教程 Spring Boot and OAuth2

Why is OAuth

它就是一个授权标准

实际上它就是一种授权机制,它的最终目的是为第三方应用颁发一个有时效性的令牌 token,使得第三方应用能够通过该令牌获取相关的资源。

具体细节看 OAuth 那篇笔记,之前那篇大致学习了一下 OAuth 的原理,这篇笔记主要是如何将其整合进 Spring Boot 里面

使用 GitHub 的 OAth 登陆

添加依赖

<!-- 这个依赖里面已经集成了 Spring Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

然后到 GitHub 里面 申请一个新的 OAuth 应用 具体操作看 OAth那篇笔记

Home 地址

http://localhost:8080

回调地址:

http://localhost:8080/login/oauth2/code/github

配置 application.yml

生成一个客户端密钥,然后将它们粘贴到 yml 上去

spring:
security:
oauth2:
client:
registration:
github:
clientId: github-client-id #这里填上 Github 控制面板上面的 ClientId
clientSecret: github-client-secret # Github 控制面板上面的 ClientSecret

然后随便写一个 Controller

@RestController
public class AuthController {
@GetMapping("/hello")
public String hello() {
return "this is resource";
}
}

启动服务访问它

http://localhost:8080/hello

可以发现它重定向到 Github 的授权页面了

授权后会重定向回来

取得数据

上面已经基本的完成了 OAth 的登陆过程,那如何取得 GitHub 返回的数据呢?

@GetMapping("/user")
public OAuth2User user(@AuthenticationPrincipal OAuth2User principal) {
return principal;
}

使用上面那个 OAuth2User 接口可以接收到

这个 @AuthenticationPrincipal 注解最基本用途是注入 UserDetails。相当于 Authentication.getPrincipal()(其实就是 Spring Security 将通过的请求的 Principal 注入进来)

整合进 Spring Security

注意,上面的认证数据默认是采用 Cookie Session的

@EnableWebSecurity
public class AuthConfigure extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
// 这里使用配置请求的白名单
.authorizeRequests(a -> a
.antMatchers("/", "/error", "/webjars/**").permitAll()
// 剩下的全部请求都需要认证
.anyRequest().authenticated()
)
// exceptionHandling 用来配置异常的配置
// 由于我们正与 Ajax 的后端对接,因此我们希望用 401 来配置端点以响应,
// 而不是重定向到登录页面的默认行为。为我们配置实现此目标。authenticationEntryPoint
.exceptionHandling(e -> e
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
)
.oauth2Login();
// @formatter:on
}
}

添加注销端点

@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
// ... existing code here
.logout(l -> l
.logoutSuccessUrl("/").permitAll()
)
// ... existing code here
// @formatter:on
}